/**
 * @file SweepDialog.cpp
 * @author  Johan Waldeback <openfms@waldeback.se>
 *
 * @section LICENSE
 *
 * Copyright (C) 2010 Johan Waldeback
 *
 * This file is part of the OpenFMS project (http://www.openfms-project.org)
 * 
 * OpenFMS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */


#ifndef __SWEEPDLG_H__
#define __SWEEPDLG_H__

#include "ModelSimulator.h"
#include <wx/dialog.h>
namespace OpenFms {

/**
 * \class SweepDialog
 * \brief Dialog to allow the user set parameters for a model simulator sweep
 */
class SweepDialog : public wxDialog
{

#ifdef MAKE_TEST
public:
	/**
	 * Dummie contructor, used when testing
	 * 
	 * Does nothing. Available when MAKE_TEST is defined.
	 */
	SweepDialog::SweepDialog() {}
#else // MAKE_TEST
private:
#endif // MAKETEST
	void setNumberOfSteps(int n);
	void setValues( int idBase, float value, float begin, float end );
	void setValue( int id, float value );
	float getValue( int id );
	void setSelectedInput( int id );
	void setSelectedOutput( int id );

	//static const int ID_OKBUTTON = 100;
	//static const int ID_CANCELBUTTON = 101;
	static const enum {
		ID_OKBUTTON = 100, /**< ID for the OK button */
		ID_CANCELBUTTON,   /**< ID for the Cancel button */
		ID_STEPS,          /**< ID for the steps edit control */
		// base   = Radio button ID
		// base+1 = Value Edit ID
		// base+2 = Begin Edit ID
		// base+3 = End Edit ID
		// Channel (n+1) base = Channel n base + CHANNEL_ID_DELTA
		ID_WINDX,          /**< ID for the wind_x radio button, and base id for all ID_WINDX_ id's */
		ID_WINDX_VALUE,    /**< ID for the wind_x VALUE edit control, has value (ID_WINDX+1) */ 
		ID_WINDX_BEGIN,    /**< ID for the wind_x BEGIN edit control, has value (ID_WINDX+2) */  
		ID_WINDX_END,      /**< ID for the wind_x END edit control, has value (ID_WINDX+3) */  
		ID_WINDY,          /**< ID for the wind_y radio button, and base id for all ID_WINDY_ id's */
		ID_WINDY_VALUE,    /**< ID for the wind_y VALUE edit control, has value (ID_WINDY+1) */ 
		ID_WINDY_BEGIN,    /**< ID for the wind_y BEGIN edit control, has value (ID_WINDY+2) */  
		ID_WINDY_END,      /**< ID for the wind_y END edit control, has value (ID_WINDY+3) */  
		ID_WINDZ,          /**< ID for the wind_z radio button, and base id for all ID_WINDZ_ id's */
		ID_WINDZ_VALUE,    /**< ID for the wind_z VALUE edit control, has value (ID_WINDZ+1) */ 
		ID_WINDZ_BEGIN,    /**< ID for the wind_z BEGIN edit control, has value (ID_WINDZ+2) */  
		ID_WINDZ_END,      /**< ID for the wind_z END edit control, has value (ID_WINDZ+3) */  
		ID_WINDYAW,          /**< ID for the wind_yaw radio button, and base id for all ID_WINDYAW_ id's */
		ID_WINDYAW_VALUE,    /**< ID for the wind_yaw VALUE edit control, has value (ID_WINDYAW+1) */ 
		ID_WINDYAW_BEGIN,    /**< ID for the wind_yaw BEGIN edit control, has value (ID_WINDYAW+2) */  
		ID_WINDYAW_END,      /**< ID for the wind_yaw END edit control, has value (ID_WINDYAW+3) */  
		ID_WINDPITCH,          /**< ID for the wind_pitch radio button, and base id for all ID_WINDPITCH_ id's */
		ID_WINDPITCH_VALUE,    /**< ID for the wind_pitch VALUE edit control, has value (ID_WINDPITCH+1) */ 
		ID_WINDPITCH_BEGIN,    /**< ID for the wind_pitch BEGIN edit control, has value (ID_WINDPITCH+2) */  
		ID_WINDPITCH_END,      /**< ID for the wind_pitch END edit control, has value (ID_WINDPITCH+3) */  
		ID_CHANNEL1,          /**< ID for the channel1 radio button, and base id for all ID_CHANNEL1_ id's */
		ID_CHANNEL1_VALUE,    /**< ID for the channel1 VALUE edit control, has value (ID_CHANNEL1+1) */ 
		ID_CHANNEL1_BEGIN,    /**< ID for the channel1 BEGIN edi control, has value (ID_CHANNEL1+2) */  
		ID_CHANNEL1_END,      /**< ID for the channel1 END edit control, has value (ID_CHANNEL1+3) */  
		ID_CHANNEL2,          /**< ID for the channel2 radio button, and base id for all ID_CHANNEL1_ id's */
		ID_CHANNEL2_VALUE,    /**< ID for the channel2 VALUE edit control, has value (ID_CHANNEL2+1) */ 
		ID_CHANNEL2_BEGIN,    /**< ID for the channel2 BEGIN edit control, has value (ID_CHANNEL2+2) */  
		ID_CHANNEL2_END,      /**< ID for the channel2 END edit control, has value (ID_CHANNEL2+3) */  
		ID_CHANNEL3,          /**< ID for the channel3 radio button, and base id for all ID_CHANNEL3_ id's */
		ID_CHANNEL3_VALUE,    /**< ID for the channel3 VALUE edit control, has value (ID_CHANNEL3+1) */ 
		ID_CHANNEL3_BEGIN,    /**< ID for the channel3 BEGIN edit control, has value (ID_CHANNEL3+2) */  
		ID_CHANNEL3_END,      /**< ID for the channel3 END edit control, has value (ID_CHANNEL3+3) */  
		ID_CHANNEL4,          /**< ID for the channel4 radio button, and base id for all ID_CHANNEL4_ id's */
		ID_CHANNEL4_VALUE,    /**< ID for the channel4 VALUE edit control, has value (ID_CHANNEL4+1) */ 
		ID_CHANNEL4_BEGIN,    /**< ID for the channel4 BEGIN edit control, has value (ID_CHANNEL4+2) */  
		ID_CHANNEL4_END,      /**< ID for the channel4 END edit control, has value (ID_CHANNEL4+3) */  
		ID_CHANNEL5,          /**< ID for the channel5 radio button, and base id for all ID_CHANNEL5_ id's */
		ID_CHANNEL5_VALUE,    /**< ID for the channel5 VALUE edit control, has value (ID_CHANNEL5+1) */ 
		ID_CHANNEL5_BEGIN,    /**< ID for the channel5 BEGIN edit control, has value (ID_CHANNEL5+2) */  
		ID_CHANNEL5_END,      /**< ID for the channel5 END edit control, has value (ID_CHANNEL5+3) */  
		ID_CHANNEL6,          /**< ID for the channel6 radio button, and base id for all ID_CHANNEL6_ id's */
		ID_CHANNEL6_VALUE,    /**< ID for the channel6 VALUE edit control, has value (ID_CHANNEL6+1) */ 
		ID_CHANNEL6_BEGIN,    /**< ID for the channel6 BEGIN edit control, has value (ID_CHANNEL6+2) */  
		ID_CHANNEL6_END,      /**< ID for the channel6 END edit control, has value (ID_CHANNEL6+3) */  
		ID_CHANNEL7,          /**< ID for the channel7 radio button, and base id for all ID_CHANNEL7_ id's */
		ID_CHANNEL7_VALUE,    /**< ID for the channel7 VALUE edit control, has value (ID_CHANNEL7+1) */ 
		ID_CHANNEL7_BEGIN,    /**< ID for the channel7 BEGIN edit control, has value (ID_CHANNEL7+2) */  
		ID_CHANNEL7_END,      /**< ID for the channel7 END edit control, has value (ID_CHANNEL7+3) */  
		ID_CHANNEL8,          /**< ID for the channel8 radio button, and base id for all ID_CHANNEL8_ id's */
		ID_CHANNEL8_VALUE,    /**< ID for the channel8 VALUE edit control, has value (ID_CHANNEL8+1) */ 
		ID_CHANNEL8_BEGIN,    /**< ID for the channel8 BEGIN edit control, has value (ID_CHANNEL8+2) */  
		ID_CHANNEL8_END,      /**< ID for the channel8 END edit control, has value (ID_CHANNEL8+3) */  

		ID_FORCE_POSX,  /**< ID for the positive force x output radio button */
		ID_FORCE_POSY,  /**< ID for the positive force y output radio button */
		ID_FORCE_POSZ,  /**< ID for the positive force z output radio button */
		ID_FORCE_NEGX,  /**< ID for the negative force x output radio button */
		ID_FORCE_NEGY,  /**< ID for the negative force y output radio button */
		ID_FORCE_NEGZ,  /**< ID for the negative force z output radio button */
		ID_TORQUE_POSX, /**< ID for the positive torque x output radio button */
		ID_TORQUE_POSY, /**< ID for the positive torque y output radio button */
		ID_TORQUE_POSZ, /**< ID for the positive torque z output radio button */
		ID_TORQUE_NEGX, /**< ID for the negative torque x output radio button */
		ID_TORQUE_NEGY, /**< ID for the negative torque y output radio button */
		ID_TORQUE_NEGZ, /**< ID for the negative torque z output radio button */
	};

private:
	float m_wind_x_value; /**< Instance variable containing the entered wind x value (only valid after transfer() has been called successfully) */
	float m_wind_x_begin; /**< Instance variable containing the entered wind x range begin value (only valid after transfer() has been called successfully) */
	float m_wind_x_end;   /**< Instance variable containing the entered wind x range end value (only valid after transfer() has been called successfully) */
	float m_wind_y_value; /**< Instance variable containing the entered wind y value (only valid after transfer() has been called successfully) */
	float m_wind_y_begin; /**< Instance variable containing the entered wind y range begin value (only valid after transfer() has been called successfully) */
	float m_wind_y_end;   /**< Instance variable containing the entered wind y range end value (only valid after transfer() has been called successfully) */
	float m_wind_z_value; /**< Instance variable containing the entered wind z value (only valid after transfer() has been called successfully) */
	float m_wind_z_begin; /**< Instance variable containing the entered wind z range begin value (only valid after transfer() has been called successfully) */
	float m_wind_z_end;   /**< Instance variable containing the entered wind z range end value (only valid after transfer() has been called successfully) */
	float m_wind_yaw_value; /**< Instance variable containing the entered wind yaw value (only valid after transfer() has been called successfully) */
	float m_wind_yaw_begin; /**< Instance variable containing the entered wind yaw range begin value (only valid after transfer() has been called successfully) */
	float m_wind_yaw_end;   /**< Instance variable containing the entered wind yaw range end value (only valid after transfer() has been called successfully) */
	float m_wind_pitch_value; /**< Instance variable containing the entered wind pitch value (only valid after transfer() has been called successfully) */
	float m_wind_pitch_begin; /**< Instance variable containing the entered wind pitch range begin value (only valid after transfer() has been called successfully) */
	float m_wind_pitch_end;   /**< Instance variable containing the entered wind pitch range end value (only valid after transfer() has been called successfully) */

	float m_channel1_value; /**< Instance variable containing the entered channel 1 value (only valid after transfer() has been called successfully) */
	float m_channel1_begin; /**< Instance variable containing the entered channel 1 range begin value (only valid after transfer() has been called successfully) */
	float m_channel1_end;   /**< Instance variable containing the entered channel 1 range end value (only valid after transfer() has been called successfully) */
	float m_channel2_value; /**< Instance variable containing the entered channel 2 value (only valid after transfer() has been called successfully) */
	float m_channel2_begin; /**< Instance variable containing the entered channel 2 range begin value (only valid after transfer() has been called successfully) */
	float m_channel2_end;   /**< Instance variable containing the entered channel 2 range end value (only valid after transfer() has been called successfully) */
	float m_channel3_value; /**< Instance variable containing the entered channel 3 value (only valid after transfer() has been called successfully) */
	float m_channel3_begin; /**< Instance variable containing the entered channel 3 range begin value (only valid after transfer() has been called successfully) */
	float m_channel3_end;   /**< Instance variable containing the entered channel 3 range end value (only valid after transfer() has been called successfully) */
	float m_channel4_value; /**< Instance variable containing the entered channel 4 value (only valid after transfer() has been called successfully) */
	float m_channel4_begin; /**< Instance variable containing the entered channel 4 range begin value (only valid after transfer() has been called successfully) */
	float m_channel4_end;   /**< Instance variable containing the entered channel 4 range end value (only valid after transfer() has been called successfully) */
	float m_channel5_value; /**< Instance variable containing the entered channel 5 value (only valid after transfer() has been called successfully) */
	float m_channel5_begin; /**< Instance variable containing the entered channel 5 range begin value (only valid after transfer() has been called successfully) */
	float m_channel5_end;   /**< Instance variable containing the entered channel 5 range end value (only valid after transfer() has been called successfully) */
	float m_channel6_value; /**< Instance variable containing the entered channel 6 value (only valid after transfer() has been called successfully) */
	float m_channel6_begin; /**< Instance variable containing the entered channel 6 range begin value (only valid after transfer() has been called successfully) */
	float m_channel6_end;   /**< Instance variable containing the entered channel 6 range end value (only valid after transfer() has been called successfully) */
	float m_channel7_value; /**< Instance variable containing the entered channel 7 value (only valid after transfer() has been called successfully) */
	float m_channel7_begin; /**< Instance variable containing the entered channel 7 range begin value (only valid after transfer() has been called successfully) */
	float m_channel7_end;   /**< Instance variable containing the entered channel 7 range end value (only valid after transfer() has been called successfully) */
	float m_channel8_value; /**< Instance variable containing the entered channel 8 value (only valid after transfer() has been called successfully) */
	float m_channel8_begin; /**< Instance variable containing the entered channel 8 range begin value (only valid after transfer() has been called successfully) */
	float m_channel8_end;   /**< Instance variable containing the entered channel 8 range end value (only valid after transfer() has been called successfully) */
	int m_steps; /**< Instance variable containing the entered number of steps (only valid after transfer() has been called successfully) */

	/**
	 * Base ID of chosen input (sweep) variable (only valid after transfer() has been called successfully)
	 *
	 * For example: if channel 3 is the selected sweep variable, this whould be set to ID_CHANNEL3
	 */
	int m_chosen_input;  

	/**
	 * ID of chosen output variable (only valid after transfer() has been called successfully)
	 *
	 * For example: if (positive) force z is choses as the output variable, this whould be set to ID_FORCE_POSZ.
	 */
	int m_chosen_output;

	float m_mass; /**< Instance variable containing the mass (only valid after transfer() has been called successfully) */

	//TODO: group in doc:
	float m_ixx; /**< Instance variable containing the X-X part of the (symentric) inertia tensor (only valid after transfer() has been called successfully) */
	float m_iyy; /**< Instance variable containing the Y-Y part of the (symentric) inertia tensor (only valid after transfer() has been called successfully) */
	float m_izz; /**< Instance variable containing the Z-Z part of the (symentric) inertia tensor (only valid after transfer() has been called successfully) */
	float m_ixy; /**< Instance variable containing the X-Y part of the (symentric) inertia tensor (only valid after transfer() has been called successfully) */
	float m_ixz; /**< Instance variable containing the X-Z part of the (symentric) inertia tensor (only valid after transfer() has been called successfully) */
	float m_iyz; /**< Instance variable containing the Y-Z part of the (symentric) inertia tensor (only valid after transfer() has been called successfully) */

	bool m_isValidData; /**< Indicates if the data in the instance variables are valid ( set to true by a successful call to transfer() ). */

	// Documentation note: doxygen documentation  for functions are put in the .cpp file
	const TCHAR *getEditName( int idEdit );
	bool parseSteps( int &result );
	bool parseFloat( float &result, int idEdit );
	//bool readInputValue( float &result, int idBase ); 
	//bool readInputBegin( float &result, int idBase );
	//bool readInputEnd( float &result, int idBase );
	int parseSelectedInput();
	int parseSelectedOutput();
	bool transfer();
public:
	SweepDialog( wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title = wxT("Sweep"));
	void OnOk( wxCommandEvent &event );
	void OnCancel( wxCommandEvent &event );
	
	bool get( ModelSimulator_environment_t &environment, ModelSimulator_inertias_t &inertias, int step );
	float select( ModelSimulator_forces_t & forces ); 
	int getNumberOfSteps();


public:
	float select( int n );
	float getInterpolatedValue( int idBase, int n, int steps );
	int getSelectedOutput();
	int getSelectedInput();




};

} // namespace OpenFms
#endif // __SWEEPDLG_H__



